//
//  Scene.cpp
//  Sinnca Engine v2
//
//  Created by Ryan Oldis on 7/27/11.
//  Copyright 2011 Sinnca Studios. All rights reserved.
//

#include "Node.h"


scene::scene(std::string n)
{
	name = n;
	draw = false;
	
	loadable = true;
	unloadable = true;
	
	currentPers = 0;
	
	state = sceneRun;
	loaded = false;
	
	percloaded = 0.0f;
	
}

scene::~scene()
{
	children.clear();
}


void scene::render()
{
	for (int i = 0; i < noOfChildren; i++)
	{
		if (children[i]->draw == true)
		{
			children[i]->render();
		}
	}
}

bool scene::pers()
{
	return currentPers;
}

void scene::load()
{
	
}

void scene::unload()
{
	children.clear();
	
	
}


/*
 Lua functions
 */
static int newScene(lua_State* L)
{
	int n = lua_gettop(L);
	if (n != 2)
	{
		return luaL_error(L, "You need to name the scene...");
	}
	
	
	luaL_checktype(L, 1, LUA_TTABLE);
	
	
	lua_newtable(L);
	
	lua_pushvalue(L, 1);
	lua_setmetatable(L, -2);
	
	lua_pushvalue(L, 1);
	lua_setfield(L, 1, "__index");
	
	 
	scene** sc = (scene**)lua_newuserdata(L, sizeof(scene*));
	*sc = new scene(luaL_checkstring(L, 2));
	
	/*
	lua_getglobal(L, "scene");
	lua_setmetatable(L, -2);
	 */
	luaL_getmetatable(L, "scene");
	lua_setmetatable(L, -2);
	
	lua_setfield(L, -2, "__self");
	
	lua_setglobal(L, luaL_checkstring(L, 2));
	
	
	return 1;
}

static int switchScene(lua_State* L)
{
	int n = lua_gettop(L);
	
	if (n == 1)
	{
		// if the scene is supposed to be switched temporaraly, don't deallocate
		if (tree->currentScene->unloadable == true)
		{
			tree->currentScene->unload();
		}
		
		scene* sc = checkScene(L, 1);
		tree->currentScene = sc;
		
		if ((tree->currentScene->loaded == false) && (tree->currentScene->loadable == true))
		{
			tree->currentScene->state = sceneLoad;
			//tree->currentScene->load();
		} else {
			
			tree->currentScene->state = sceneRun;
		}
		
		
	}
	return 0;
}

static int clear(lua_State* L)
{
	return 0;
}


scene* checkScene(lua_State* L, int ind)
{
	void* ud = 0;
	
	// check for table object
	luaL_checktype(L, ind, LUA_TTABLE);
	
	// push the key we're looking for (in this case, it's "__self")
	lua_pushstring(L, "__self");
	// get our table
	lua_gettable(L, ind);
	
	// cast userdata pointer to "Node" type
	ud = dynamic_cast<scene*>((scene*)lua_touserdata(L, -1));
	luaL_argcheck(L, ud != 0, ind, "Incompatible 'node' type...");
	
	return *((scene**)ud);
	
	/*
	void* ud = dynamic_cast<scene*>((scene*)lua_touserdata(L, ind));
	luaL_argcheck(L, ud != 0, ind, "A 'scene' type node is required...");
	
	return *((scene**)ud);
	*/
}


static const luaL_Reg sceneFuncs[] = {
	
	{"new", newScene},
	{"switchScene", switchScene},
	{NULL, NULL}
};

static const luaL_Reg sceneGc[] = {
	
	{"__gc", clear},
	{NULL, NULL}
	
};


void registerScene(lua_State* L)
{
	/*
	luaL_register(L, "scene", sceneFuncs);
	lua_pushvalue(L,-1);
	lua_setfield(L, -2, "__index");
	 */
	
	luaL_newmetatable(L, "scene");
	
	luaL_register(L, 0, sceneGc);
	luaL_register(L, 0, sceneFuncs);
	lua_pushvalue(L, -1);
	
	lua_setfield(L, -2, "__index");
	
	
	
	luaL_register(L, "scene", sceneFuncs);
	
}